package com.ouc.pampas.controller;
import com.google.common.net.MediaType;
import com.ouc.pampas.ActionEngine;
import com.ouc.pampas.Invoker;
import com.ouc.pampas.Mapping;
import com.ouc.pampas.ThreadVars;
import io.terminus.common.utils.Joiners;
import io.terminus.common.utils.JsonMapper;
import io.terminus.pampas.client.Action;
import io.terminus.pampas.client.action.LoginAction;
import io.terminus.pampas.client.action.LogoutAction;
import io.terminus.pampas.engine.ActionInvoker;
import io.terminus.pampas.engine.utils.Domains;
import io.terminus.pampas.webc.utils.CookieBuilder;
import io.terminus.pampas.webc.utils.LoginInfo;
import java.io.IOException;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MappingHandler {
	@Autowired
	private Invoker invoker;
	@Autowired
	private ActionEngine actionEngine;

	@SuppressWarnings("unchecked")
	@PostConstruct
	public void init() {
		this.actionEngine.registerOnce(LoginAction.class, new ActionInvoker() {
			public boolean invoke(Action loginAction, HttpServletRequest request, HttpServletResponse response) {
				if (((LoginAction) loginAction).getUserId() == null) {
					return false;
				}
				LoginInfo loginInfo = new LoginInfo(((LoginAction) loginAction).getUserId(), request.getRemoteAddr());

				String domain = "." + Domains.removeSubDomain(ThreadVars.getDomain());
				Cookie cookie = CookieBuilder.from("pms_id", loginInfo.toCookieKey(), domain).httpOnly()
						.maxAge(((LoginAction) loginAction).getMaxAge().intValue()).build();

				response.addCookie(cookie);
				return false;
			}
		});
		this.actionEngine.registerOnce(LogoutAction.class, new ActionInvoker() {
			public boolean invoke(Action action, HttpServletRequest request, HttpServletResponse response) {
				String domain = "." + Domains.removeSubDomain(ThreadVars.getDomain());
				Cookie cookie = CookieBuilder.from("pms_id", null, domain).httpOnly().maxAge(0).build();
				response.addCookie(cookie);
				return false;
			}
		});
	}

	public boolean handle(String path, HttpServletRequest request, HttpServletResponse response,
			Map<String, Object> context) {
		String method = request.getMethod().toUpperCase();
		Mapping mapping = this.invoker.mappingMatch(ThreadVars.getAppKey(),Joiners.COLON.join(method, path, new Object[0]));
		if (mapping == null) {
			return false;
		}
		response.setContentType(MediaType.JSON_UTF_8.toString());
		Object result = this.invoker.mappingInvoke(mapping, path, context);
		if (((result instanceof Action)) && (this.actionEngine.handler((Action) result, request, response))) {
			return true;
		}
		Object realResult = (result instanceof Action) ? ((Action) result).getData() : result;
		try {
			response.getWriter().write(JsonMapper.JSON_NON_EMPTY_MAPPER.toJson(realResult));
		} catch (IOException e) {
		}
		return true;
	}
}
